package main

import (
	"crypto/rsa"
	"crypto/rand"
	"fmt"
	"encoding/pem"
	"crypto/x509"
	"os"
	"log"
	"io/ioutil"
	"errors"
)
var privite_key_path = "D:/gopath/src/git.oschina.net/fanbuchi/redpack/conf/rsa/pem/rsa_private_key.pem"
var public_key_path = "D:/gopath/src/git.oschina.net/fanbuchi/redpack/conf/rsa/pem/rsa_public_key.pem"

func main() {

	// 生成公钥和私钥
	generatePub(generatePrivate())
	/*src := []byte(`{"name":"酷走天涯"}`)
	// 公钥加密
	cryptoData,error := rsaEncrypt(src)
	if error != nil {
		log.Fatal(error)
	}
	fmt.Println("加密:",cryptoData)

	// 私钥解密
	dst,error := rsaDecrypt(cryptoData)
	if error != nil {
		log.Fatal(error)
	}
	fmt.Println("解密:",string(dst))*/
}

// 生成私钥
func generatePrivate() *rsa.PrivateKey{


	privateKey,error :=  rsa.GenerateKey(rand.Reader,2048)
	if error != nil {
		fmt.Println(error)
	}
	derStream := x509.MarshalPKCS1PrivateKey(privateKey)
	block := &pem.Block{Type:"RSA PRIVATE KEY",Bytes:derStream}

	file,error := os.Create(privite_key_path)
	if error != nil {
		fmt.Println(error)
	}
	error = pem.Encode(file,block)
	if error != nil {
		fmt.Println(error)
	}
	return privateKey
}

// 生成公钥
func generatePub(privateKey *rsa.PrivateKey){
	publicKey := privateKey.Public()
	derStream,error := x509.MarshalPKIXPublicKey(publicKey)
	if error != nil{
		fmt.Println(error)
	}
	block := &pem.Block{Type:"RSA PUBLIC KEY",Bytes:derStream}
	file,error := os.Create(public_key_path)
	if error != nil {
		fmt.Println(error)
	}
	error = pem.Encode(file,block)
	if error != nil {
		fmt.Println(error)
	}
}

// 公钥加密
func rsaEncrypt(origData []byte) ([]byte, error) {

	// 从文件中读取公钥编码字节流
	file,error := os.Open(public_key_path)
	if error != nil{
		log.Fatal(error)
	}


	publicKey,error := ioutil.ReadAll(file)
	if error != nil{
		log.Fatal(error)
	}
	// 解码对应的block块数据
	block, _ := pem.Decode(publicKey)
	if block == nil {
		return nil, errors.New("public key error")
	}

	// 获取公钥key值
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	pub := pubInterface.(*rsa.PublicKey)

	// 加密数据
	return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}



// 私钥解密
func rsaDecrypt(ciphertext []byte) ([]byte, error) {

	// 从文件中读取私钥pem字节流
	file,error := os.Open(privite_key_path)
	if error != nil{
		log.Fatal(error)
	}
	privateKey,error := ioutil.ReadAll(file)
	if error != nil{
		log.Fatal(error)
	}
	// 解码出对应的block值
	block, _ := pem.Decode(privateKey)
	if block == nil {
		return nil, errors.New("private key error!")
	}

	// 获取私钥对象
	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}

	// 解密文件
	return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}